package com.example.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.example.commons.SysConstant;
import com.example.config.AlipayConfig;
import com.example.entity.Order;
import com.example.service.AlipayService;
import com.example.service.OrderService;
import jakarta.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

/**
 * @author 游家纨绔
 * @dateTime 2023-09-11 07:30
 * @apiNote TODO
 */
@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {

	@Resource
	private OrderService orderService;
	@Resource
	private AlipayConfig alipayConfig;

	// 获取自定义配置的 alipay 的客户端
	@NonNull
	private DefaultAlipayClient getDefaultAlipayClient() {
		DefaultAlipayClient alipayClient = new DefaultAlipayClient(
				alipayConfig.getGatewayUrl()
				, alipayConfig.getAppId()
				, alipayConfig.getMerchantPrivateKey()
				, SysConstant.FORMAT
				, alipayConfig.getCharset()
				, alipayConfig.getAlipayPublicKey()
				, alipayConfig.getSignType()
		);
		return alipayClient;
	}


	@Override
	public String createTrade() {
		// 1、创建订单
		log.info("创建订单");
		Order order = orderService.createOrder();

		// 2、获取客户端对象（不使用默认的AlipayClient对象）
		DefaultAlipayClient alipayClient = getDefaultAlipayClient();

		// 3、创建支付请求对象
		AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
		// 设置请求的异步通知路径
		request.setNotifyUrl(alipayConfig.getNotifyUrl());
		// 设置请求的同步通知路径
		request.setReturnUrl(alipayConfig.getReturnUrl());
		// 组装 biz_content 请求参数的集合
		Map<String, Object> map = new HashMap<>();
		map.put("out_trade_no", order.getOrderNo());
		map.put("total_amount", order.getTotalAmount());
		map.put("subject", order.getSubject());
		map.put("product_code", "FAST_INSTANT_TRADE_PAY");
		String bizContent = JSON.toJSONString(map);
		request.setBizContent(bizContent);

		// 重点：调用远程的支付宝支付接口
		AlipayTradePagePayResponse response = null;
		try {
			response = alipayClient.pageExecute(request);
			// 判断是否支付成功
			if (response.isSuccess()) {
				// 创建支付请求的响应体是无法获取参数信息的
				log.info("商户订单号: " + response.getOutTradeNo() + ", 支付交易号: " + response.getTradeNo() + ", 创建订单成功");
				// 如果想获取对应的参数信息应该在 异步请求 或者 返回请求 中获取，这里直接从 Order 中获取数据
				log.info("商户订单号: " + order.getOrderNo() + ", 创建订单成功");
			} else {
				// 创建支付请求的响应体是无法获取参数信息的
				log.error("商户订单号: " + response.getOutTradeNo() + ", 支付交易号: " + response.getTradeNo() + ", 创建订单失败");
				// 如果想获取对应的参数信息应该在 异步请求 或者 返回请求 中获取，这里直接从 Order 中获取数据
				log.error("商户订单号: " + order.getOrderNo() + ", 创建订单失败");
			}
		} catch (AlipayApiException e) {
			throw new RuntimeException(e);
		}

		// 这里的 Body 是一个字符串形式的 HTML
		return response.getBody();
	}

	// 关闭订单
	@Override
	public void closeTrade(String orderNo) throws AlipayApiException {
		// 1、获取 alipay 的客户端
		DefaultAlipayClient alipayClient = getDefaultAlipayClient();
		// 2、创建一个关闭请求对象
		AlipayTradeCloseRequest alipayTradeCloseRequest = new AlipayTradeCloseRequest();
		// 3、设置参数
		JSONObject bizContent = new JSONObject();
		bizContent.put("out_trade_no", orderNo); // 表示支付的订单号，商家自己生成的
		alipayTradeCloseRequest.setBizContent(bizContent.toString());
		// 4、发送请求关闭订单
		AlipayTradeCloseResponse response = alipayClient.execute(alipayTradeCloseRequest);
		if (response.isSuccess()) {
			log.info("关闭订单成功!");
		} else {
			log.info("关闭订单失败!");
		}
		// 5、更新订单
		orderService.updateOrderStatus(Order.builder().orderNo(orderNo).build(), SysConstant.CANCEL_SUCCESS);
	}

	@Override
	public void refund(String orderNo) throws AlipayApiException {
		// 1、获取 alipay 的客户端
		DefaultAlipayClient alipayClient = getDefaultAlipayClient();
		// 2、创建一个退款请求对象
		AlipayTradeRefundRequest alipayTradeRefundRequest = new AlipayTradeRefundRequest();
		Order order = orderService.getByTradeNo(orderNo);
		// 3、组装业务参数
		JSONObject json = new JSONObject();
		json.put("out_trade_no", orderNo);
		json.put("refund_amount", order.getTotalAmount());
		alipayTradeRefundRequest.setBizContent(json.toString());
		// 4、请求支付宝退款
		AlipayTradeRefundResponse response = alipayClient.execute(alipayTradeRefundRequest);
		if (response.isSuccess()) {
			log.info("退款成功，金额原路返回" + response.getBody());
		} else {
			log.info("退款失败" + response.getCode());
			orderService.updateOrderStatus(Order.builder().id(order.getId()).build(), SysConstant.REFUD_FAIL);
		}
		// 5、更新订单状态
		orderService.updateOrderStatus(Order.builder().id(order.getId()).build(), SysConstant.REFUD_SUCCESS);
	}

	@Override
	public String queryRefund(String orderNo) throws AlipayApiException {
		// 1、获取 alipay 的客户端
		DefaultAlipayClient alipayClient = getDefaultAlipayClient();
		// 2、创建一个退款查询请求对象
		AlipayTradeFastpayRefundQueryRequest fastPayRefundQueryRequest = new AlipayTradeFastpayRefundQueryRequest();
		// 3、组装业务参数
		JSONObject json = new JSONObject();
		json.put("out_trade_no", orderNo);   // 商户订单号
		json.put("out_request_no", orderNo); // 退款对应的退款请求号
		fastPayRefundQueryRequest.setBizContent(json.toString());
		// 4、请求支付宝退款查询
		AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(fastPayRefundQueryRequest);
		if (response.isSuccess()) {
			log.info("查询退款信息成功" + response.getBody());
			return response.getBody();
		} else {
			log.info("查询退款信息失败" + response.getCode());
			return response.getCode();
		}
	}

}
